package com.probox.common.entity.service.product.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import com.probox.common.core.enums.DataStatus;
import com.probox.common.core.exception.ProductException;
import com.probox.common.core.text.Convert;
import com.probox.common.core.utils.money.MoneyUtils;
import com.probox.product.api.domain.ProductSkuItemVo;
import com.probox.product.api.domain.ProductSkuVo;
import com.probox.product.api.domain.SaleProductVo;
import com.probox.common.entity.domain.product.vo.ProductSaveVo;
import com.probox.common.entity.domain.product.vo.SkuSaveVo;
import com.probox.common.entity.service.product.IProductPropertyValuesService;
import com.probox.common.entity.service.product.IProductSkuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.probox.common.entity.mapper.product.ProductsSkuMapper;
import com.probox.common.entity.domain.product.ProductSku;
import org.springframework.transaction.annotation.Transactional;

/**
 * 产品SKU信息Service业务层处理
 *
 *
 * @date 2021-06-01
 */
@Service
@Transactional
public class ProductSkuServiceImpl extends ServiceImpl<ProductsSkuMapper, ProductSku> implements IProductSkuService {
    @Autowired
    private ProductsSkuMapper productsSkuMapper;

    @Autowired
    private IProductPropertyValuesService iProductPropertyValuesService;

    @Override
    public int saleSku(SaleProductVo vo) {
        return productsSkuMapper.saleSku(vo);
    }

    /**
     * 查询产品SKU信息
     *
     * @param skuUid 产品SKU信息ID
     * @return 产品SKU信息
     */
    @Override
    public ProductSku selectProductsSkuById(Long skuUid) {
        return this.getById(skuUid);
    }


    /**
     * 修改品SKU信息
     *
     * @param productSku 产品SKU信息
     * @return 产品SKU信息
     */
    @Override
    public void updateProductsSku(ProductSku productSku) {
        boolean b = this.updateById(productSku);
        if (!b) throw new ProductException("操作失败,请稍后再试！");
    }

    /**
     * 查询产品SKU信息列表
     *
     * @param productUid 商品ID
     * @return 产品SKU信息
     */
    @Override
    public List<ProductSku> queryList(Long productUid) {
        QueryWrapper<ProductSku> queryWrapper = Wrappers.query();
        queryWrapper.ne("SKU_STATUS", DataStatus.delete.getKey());
        queryWrapper.eq("PRODUCT_UID", productUid);
        return productsSkuMapper.selectList(queryWrapper);
    }

    @Override
    public List<ProductSku> getOnlineSkuList(Long productUid) {
        QueryWrapper<ProductSku> queryWrapper = Wrappers.query();
        queryWrapper.eq("SKU_STATUS", DataStatus.valid.getKey());
        queryWrapper.eq("PRODUCT_UID", productUid);
        return productsSkuMapper.selectList(queryWrapper);
    }

    /**
     * 新增产品SKU信息
     *
     * @param productSaveVo 商品信息vo
     * @return 结果
     */
    @Override
    public Long insertProductsSku(ProductSaveVo productSaveVo) {
        AtomicReference<Long> stockNumber = new AtomicReference<>(0L);
        List<SkuSaveVo> skuSaveVo = productSaveVo.getSkuSaveVo();
        if (ObjectUtil.isNotEmpty(skuSaveVo)) {
            skuSaveVo.forEach(sku -> {
                ProductSku productSku = saveSku(sku, productSaveVo);
                String valuesUid = iProductPropertyValuesService.insertProductSkuValues(productSaveVo, sku, productSku.getSkuUid());
                productSku.setValuesUid(valuesUid);
                boolean save = this.updateById(productSku);
                if (!save) throw new ProductException("操作失败,请稍后再试!");
                stockNumber.set(stockNumber.get() + productSku.getStockNumber());
            });
        }
        return stockNumber.get();
    }

    /**
     * 修改产品SKU信息
     *
     * @param productSaveVo 商品信息vo
     * @return 结果
     */
    @Override
    public Long updateProductsSku(ProductSaveVo productSaveVo) {
        AtomicReference<Long> stockNumber = new AtomicReference<>(0L);
        List<SkuSaveVo> skuSaveVo = productSaveVo.getSkuSaveVo();
        Long[] uids = {productSaveVo.getProductUid()};// 先无效所有sku
        updateSkuStatus(productSaveVo, uids);
        if (ObjectUtil.isNotEmpty(skuSaveVo)) {
            skuSaveVo.forEach(sku -> {
                ProductSku productSku = null;
                if (ObjectUtil.isEmpty(sku.getId())) productSku = saveSku(sku, productSaveVo);
                else {
                    ProductSku byId = this.getById(sku.getId());
                    if (ObjectUtil.isNotEmpty(byId)) productSku = editSku(sku, productSaveVo);
                    else productSku = saveSku(sku, productSaveVo);
                }
                Long skuUid = productSku.getSkuUid();
                String valuesUid = iProductPropertyValuesService.insertProductSkuValues(productSaveVo, sku, skuUid);
                productSku.setValuesUid(valuesUid);
                boolean save = this.updateById(productSku);
                if (!save) throw new ProductException("操作失败,请稍后再试!");
                stockNumber.set(stockNumber.get() + productSku.getStockNumber());
            });
        }
        return stockNumber.get();
    }

    /**
     * 新增sku
     *
     * @param skuSaveVo     sku vo信息
     * @param productSaveVo 商品 vo信息
     * @return
     */
    private ProductSku saveSku(SkuSaveVo skuSaveVo, ProductSaveVo productSaveVo) {
        ProductSku productSku = new ProductSku();
        productSku.setSkuNo(skuSaveVo.getSkuNo());
        productSku.setCostPrice(MoneyUtils.changeY2B(skuSaveVo.getCostPrice()));
        productSku.setSkuRetailPrice(MoneyUtils.changeY2B(skuSaveVo.getSkuRetailPrice()));
        productSku.setSkuTradePrice(productSku.getSkuRetailPrice());
        productSku.setImgCoverUrl(skuSaveVo.getImgCoverUrl());
        productSku.setStockNumber(Long.valueOf(skuSaveVo.getStockNumber()));
        if (skuSaveVo.getIsUse()) productSku.setSkuStatus(DataStatus.valid.getKey());
        else productSku.setSkuStatus(DataStatus.invalid.getKey());
        StringBuffer valuesName = new StringBuffer();
        List<HashMap> data = skuSaveVo.getData();
        data.forEach(map -> valuesName.append("," + map.get("value_name")));
        String valuesNameStr = valuesName.toString();
        productSku.setValuesDesc(valuesNameStr.substring(1, valuesNameStr.length()));
        productSku.setSaleAmount(0);
        productSku.setCreateUid(productSaveVo.getUserUid());
        productSku.setCreateName(productSaveVo.getUserName());
        productSku.setCreateTime(productSaveVo.getTime());
        productSku.setUpdateUid(productSaveVo.getUserUid());
        productSku.setUpdateName(productSaveVo.getUserName());
        productSku.setUpdateTime(productSaveVo.getTime());
        productSku.setProductUid(productSaveVo.getProductUid());
        productSku.setImgCoverUrl(skuSaveVo.getImgCoverUrl());
        boolean save = this.save(productSku);
        if (!save) throw new ProductException("操作失败,请稍后再试!");
        return productSku;
    }

    /**
     * 修改sku
     *
     * @param skuSaveVo
     * @param productSaveVo
     * @return
     */
    private ProductSku editSku(SkuSaveVo skuSaveVo, ProductSaveVo productSaveVo) {
        ProductSku productSku = this.getById(skuSaveVo.getId());
        if (ObjectUtil.isNotEmpty(productSku)) {
            productSku.setSkuNo(skuSaveVo.getSkuNo());
            productSku.setCostPrice(MoneyUtils.changeY2B(skuSaveVo.getCostPrice()));
            productSku.setSkuRetailPrice(MoneyUtils.changeY2B(skuSaveVo.getSkuRetailPrice()));
            productSku.setSkuTradePrice(MoneyUtils.changeY2B(skuSaveVo.getSkuTradePrice()));
            productSku.setImgCoverUrl(skuSaveVo.getImgCoverUrl());
            productSku.setStockNumber(Long.valueOf(skuSaveVo.getStockNumber()));
            iProductPropertyValuesService.editProductSkuValues(productSaveVo, productSku.getSkuUid()); //无效sku属性信息
            if (skuSaveVo.getIsUse()) productSku.setSkuStatus(DataStatus.valid.getKey());
            else productSku.setSkuStatus(DataStatus.invalid.getKey());
            productSku.setUpdateUid(productSaveVo.getUserUid());
            productSku.setUpdateName(productSaveVo.getUserName());
            productSku.setUpdateTime(productSaveVo.getTime());
            boolean b = this.updateById(productSku);
            if (!b) throw new ProductException("修改失败,请稍后再试");
        }
        return productSku;
    }

    /**
     * 查询详情的sku
     *
     * @param productSkus sku信息
     * @return
     */
    @Override
    public List<SkuSaveVo> getSkuSaveVoList(List<ProductSku> productSkus) {
        List<SkuSaveVo> list = new ArrayList<>();
        productSkus.forEach(sku -> {
            SkuSaveVo skuSaveVo = new SkuSaveVo();
            skuSaveVo.setImgCoverUrl(sku.getImgCoverUrl());
            skuSaveVo.setSkuNo(sku.getSkuNo());
            skuSaveVo.setStockNumber(Convert.toStr(sku.getStockNumber()));
            skuSaveVo.setId(skuSaveVo.getId());
            if (DataStatus.valid.getKey().equals(sku.getSkuStatus())) skuSaveVo.setIsUse(true);
            else skuSaveVo.setIsUse(false);
            skuSaveVo.setCostPrice(MoneyUtils.changeF2B(sku.getCostPrice()));
            skuSaveVo.setSkuTradePrice(MoneyUtils.changeF2B(sku.getSkuTradePrice()));
            skuSaveVo.setSkuRetailPrice(MoneyUtils.changeF2B(sku.getSkuRetailPrice()));
            skuSaveVo.setData(iProductPropertyValuesService.querySkuValyesNames(sku.getSkuUid()));
            if (ObjectUtil.isEmpty(skuSaveVo.getData())) skuSaveVo.setData(new ArrayList<>());
            skuSaveVo.setId(sku.getSkuUid());
            list.add(skuSaveVo);
        });
        return list;
    }

    /**
     * 清除sku
     *
     * @param productSaveVo 商品信息vo
     * @param productUids   商品uid集合
     */
    @Override
    public void updateSkuStatus(ProductSaveVo productSaveVo, Long[] productUids) {
        UpdateWrapper<ProductSku> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("SKU_STATUS", DataStatus.delete.getKey());
        updateWrapper.set("UPDATE_UID", productSaveVo.getUserUid());
        updateWrapper.set("UPDATE_NAME", productSaveVo.getUserName());
        updateWrapper.set("UPDATE_TIME", productSaveVo.getTime());
        updateWrapper.in("PRODUCT_UID", productUids);
        this.update(updateWrapper);

    }

    /**
     * api 获取商品sku详细信息
     * @param productUid
     * @param skuVo
     * @return
     */
    @Override
    public ProductSkuVo getSkuItemVo(Long productUid, ProductSkuVo skuVo) {
        List<ProductSkuItemVo> list = new ArrayList<>();
        List<ProductSku> onlineSkuList = getOnlineSkuList(productUid);
        if (ObjectUtil.isEmpty(onlineSkuList)) return null;
        AtomicReference<BigDecimal> min = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> max = new AtomicReference<>(BigDecimal.ZERO);
        onlineSkuList.forEach(sku -> {
            ProductSkuItemVo vo = new ProductSkuItemVo();
            vo.setSkuUid(sku.getSkuUid());
            vo.setImage(sku.getImgCoverUrl());
            vo.setPrice(MoneyUtils.changeF2B(sku.getSkuRetailPrice()));
            vo.setStockNumber(sku.getStockNumber());
            String valuesDesc = sku.getValuesDesc();
            String[] split = valuesDesc.split(",");
            List<String> difference = new ArrayList<>();
            for (int i = 0; i < split.length; i++) {
                difference.add(split[i]);
            }
            BigDecimal bigDecimal = new BigDecimal(vo.getPrice());
            if(min.get() ==BigDecimal.ZERO){
                min.set(bigDecimal);
            }else{
                if(min.get().compareTo(bigDecimal) > 0){
                    min.set(bigDecimal);
                }
            }
            if(bigDecimal.compareTo(max.get()) > 0){
                max.set(bigDecimal);
            }
            vo.setDifference(difference);
            list.add(vo);
        });
        skuVo.setDifference(list);
        skuVo.setPriceBetween(min.get()+"~"+max.get());
        return skuVo;
    }

}
